Using EWS to attempt to get Attachments  and download to c:\ drive folder nothing happens

I have been trying to figure out why when I run this code nothing happens, there are no errors being caught by VS, and then app opens a console window and then it closes rapidly I do not see anything in the console window, but there are no attachments downloaded and nothing happens.

 What I'm attempting to do is use the EWS 2.0  to download the email attachment to the c drive folder temp and I only need the most recent email  .

         

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Exchange.WebServices.Data;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;



namespace GetAttachments
{

    class Program
    {
        static void Main(string[] args)
        {
           

            ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
            service.EnableScpLookup = false;
            service.Credentials = new WebCredentials("USN", "Password", "domain");

            service.TraceEnabled = true;
            service.TraceFlags = TraceFlags.All;
            ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;

            service.Url = new Uri("https://<IP address of Exchange Server>/ews/exchange.asmx");

   

        }
        public static void GetAttachmentsFromEmail(ExchangeService service, ItemId itemId)
        {
            // Bind to an existing message item and retrieve the attachments collection.
            // This method results in an GetItem call to EWS.
            EmailMessage message = EmailMessage.Bind(service, itemId, new PropertySet(ItemSchema.Attachments));

            // Iterate through the attachments collection and load each attachment.
            foreach (Attachment attachment in message.Attachments)
            {
                if (attachment is FileAttachment)
                {
                    FileAttachment fileAttachment = attachment as FileAttachment;

                    // Load the attachment into a file.
                    // This call results in a GetAttachment call to EWS.
                    fileAttachment.Load("C:\\temp\\" + fileAttachment.Name);

                    Console.WriteLine("File attachment name: " + fileAttachment.Name);
                }
                else // Attachment is an item attachment.
                {
                    ItemAttachment itemAttachment = attachment as ItemAttachment;

                    // Load attachment into memory and write out the subject.
                    // This does not save the file like it does with a file attachment.
                    // This call results in a GetAttachment call to EWS.
                    itemAttachment.Load();

                    Console.WriteLine("Item attachment name: " + itemAttachment.Name);
                }
            }
        }

     
        public static void SaveEmailAttachment(ExchangeService service, ItemId itemId)
        {
            // Bind to an existing message item and retrieve the attachments collection.
            // This method results in an GetItem call to EWS.
            EmailMessage message = EmailMessage.Bind(service, itemId, new PropertySet(ItemSchema.Attachments));

            foreach (Attachment attachment in message.Attachments)
            {
                if (attachment is ItemAttachment)
                {
                    ItemAttachment itemAttachment = attachment as ItemAttachment;
                    itemAttachment.Load(ItemSchema.MimeContent);
                    string fileName = "C:\\temp\\" + itemAttachment.Item.Subject + ".eml";

                    // Write the bytes of the attachment into a file.
                    System.IO.File.WriteAllBytes(fileName, itemAttachment.Item.MimeContent.Content);

                    Console.WriteLine("Email attachment name: " + itemAttachment.Item.Subject + ".eml");
                }
            }
        }

        private static bool CertificateValidationCallBack(
        object sender,
        System.Security.Cryptography.X509Certificates.X509Certificate certificate,
        System.Security.Cryptography.X509Certificates.X509Chain chain,
        System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
            // If the certificate is a valid, signed certificate, return true.
            if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
            {
                return true;
            }

            // If there are errors in the certificate chain, look at each error to determine the cause.
            if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
            {
                if (chain != null && chain.ChainStatus != null)
                {
                    foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
                    {
                        if ((certificate.Subject == certificate.Issuer) &&
                           (status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
                        {
                            // Self-signed certificates with an untrusted root are valid. 
                            continue;
                        }
                        else
                        {
                            if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
                            {
                                // If there are any other errors in the certificate chain, the certificate is invalid,
                                // so the method returns false.
                                return false;
                            }
                        }
                    }
                }

                // When processing reaches this line, the only errors in the certificate chain are 
                // untrusted root errors for self-signed certificates. These certificates are valid
                // for default Exchange server installations, so return true.
                return true;
            }
            else
            {
                // In all other cases, return false.
                return true;
            }
        }
    }
}
 

July 2nd, 2015 12:45pm

I'm probably missing something, but isn't it just going to execute this bit below?  I don't see where the attachment saving code gets called.

        static void Main(string[] args) {
          

           
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
            service
.EnableScpLookup = false;
            service
.Credentials = new WebCredentials("USN", "Password", "domain");

            service
.TraceEnabled = true;
            service
.TraceFlags = TraceFlags.All;
           
ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;

            service
.Url = new Uri(<a href="https:///ews/exchange.asmx">https://<IP address of Exchange Server>/ews/exchange.asmx);
  
       
}

Free Windows Admin Tool Kit Click here and download it now
July 3rd, 2015 6:51am

ok, you got me,  I'm just starting with C# and .NET.

I'm trying to learn how to use the EWS  and C#... it looks interesting to use and it would help solve an issue we have here at work.

how would I make that call to save the attachments?

July 6th, 2015 10:02am

I had the idea that you had some complete cpde from somewhere, but were just having trouble getting it working. But there is quite a lot missing here. The code in Main() just sets the session up, and then finishes without doing anything. You need a bit that calls

SaveEmailAttachment(ExchangeService service, ItemId itemId)

to save the attachments of a message.  But what is missing is how you identify which message you want to do it with.  Is the code from somewhere else, or are you writing it from scratch?

Free Windows Admin Tool Kit Click here and download it now
July 6th, 2015 12:15pm

I got the code from a MS sample that isn't complete.. or at least they don't tell you what you need, been debugging for over a week, learning as i go...

Any and all assistance is GREATLY Appreciated..... As i don't know a lot about any of this... Just been tasked to do a project for a VP request

July 6th, 2015 12:30pm

Okay, it'll need something adding to it, but I don't know what you're trying to do yet. How are you to choose or identify which message to save the attachments from?  Or is it to do it for all messages in the inbox, or something like that? There is code there to open an EWS session, and a subroutine to save the attachments for a single message. We have to decide which message to pass to the subroutine, or we can do it for all message in the inbox, or some other folder, or hierarchy.
Free Windows Admin Tool Kit Click here and download it now
July 6th, 2015 1:11pm

Ok, here is the request as I was told:

"Download the current email message's attachment to the C drive..." 

background:

this email box is unattended and we are sent a rough XML file  weekly or biweekly, so basically once the email attachment is downloaded. probably need to delete the current email or move it to another folder.

I know part of the code works as I was able to use it to send an email to myself... when testing the EWS. it is the part that you keep saying that works.. LOL ( yes the code to send email is removed and this new code is in its place)


July 6th, 2015 1:18pm

The new code looks like it will save attachments, yes, but it is in subroutines that don't get called by anything.

But anyway, I have a bit more to work on now, and it sounds like a simple enough task.  I should be able to come up with something tomorrow.

If you want to play with it in the meantime, it will involve doing FindItems on the Inbox

https://msdn.microsoft.com/en-us/library/jj220574(v=exchg.80).aspx

taking the (presumably) only item in the returned results, and passing its ItemId to your SaveEmailAttachment(ExchangeService service, ItemId itemId) function, and then moving it somewhere

https://msdn.microsoft.com/en-us/library/office/dn600291(v=exchg.150).aspx

Free Windows Admin Tool Kit Click here and download it now
July 6th, 2015 1:30pm

Ok, thanks for the help so far, I'll ping this reply tomorrow to see if you got time to assist..   thanks
July 6th, 2015 1:49pm

Ok, here is the request as I was told:

"Download the current email message's attachment to the C drive..." 

background:

this email box is unattended and we are sent a rough XML file  weekly or biweekly, so basically once the email attachment is downloaded. probably need to delete the current email or move it to another folder.

I know part of the code works as I was able to use it to send an email to myself... when testing the EWS. it is the part that you keep saying that works.. LOL ( yes the code to send email is removed and this new code is in its place)


  • Edited by SPSAdminTC Monday, July 06, 2015 5:27 PM
Free Windows Admin Tool Kit Click here and download it now
July 6th, 2015 5:17pm

Okay, here is a fairly simple version.  I'm not the best at this sort of thing, but it works for me.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Exchange.WebServices.Data;

namespace EWS_Save_Attachments
{
    class Program
    {
        static void Main(string[] args)
        {
            ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
            service.EnableScpLookup = false;
            service.Credentials = new WebCredentials("username", "password", "domain");
            service.Url = new Uri("https://whatever/ews/Exchange.asmx");
            ItemView view = new ItemView(100);
            FindItemsResults<Item> items = service.FindItems(WellKnownFolderName.Inbox, view);
            foreach(Item item in items)
            {
                Console.WriteLine(item.Subject);
                EmailMessage message = EmailMessage.Bind(service, item.Id, new PropertySet(ItemSchema.Attachments));
                foreach(Attachment attachment in message.Attachments)
                {
                    if (attachment is FileAttachment)
                    {
                        FileAttachment fileAttachment = attachment as FileAttachment;
                        fileAttachment.Load("C:\\TEMP\\" + fileAttachment.Name);
                    }
                }
                item.Delete(DeleteMode.MoveToDeletedItems);
            }
        }
    }
}

July 7th, 2015 5:33am

that looks promising, but I need to get the certificate call...

I think I found a smaller bit of code to try.. let me test this... 

thanks for the help... 

Free Windows Admin Tool Kit Click here and download it now
July 7th, 2015 10:04am

that works.. now to find out if they want to  save the actual email also.. but thanks  a BUNCH!!!!
July 7th, 2015 10:16am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics